package com.huitong.auth.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import com.huitong.auth.domain.dto.LoginDTO;
import com.huitong.auth.domain.dto.PasswordDTO;
import com.huitong.auth.service.TokenService;
import com.huitong.common.core.domain.Result;
import com.huitong.common.core.exception.CaptchaException;
import com.huitong.common.redis.constant.CacheConstant;
import com.huitong.common.redis.utils.RedisUtils;
import com.huitong.common.satoken.domain.vo.LoginVO;
import com.huitong.common.satoken.utils.LoginUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * 令牌控制层
 *
 * @author fromdrowning
 * @date 2024/3/21 15:33
 */
@RequiredArgsConstructor
@Validated
@RestController
public class TokenController {

    /**
     * 令牌服务层
     */
    private final TokenService tokenService;

    /**
     * 登录系统
     *
     * @param loginDTO 用户输入的登录信息
     * @return 用户登录信息
     */
    @SaIgnore
    @PostMapping("/login")
    public Result<LoginVO> login(@Validated @RequestBody LoginDTO loginDTO) {
        verifyCaptcha(loginDTO.getCaptcha(), loginDTO.getUuid());
        LoginVO loginVO = tokenService.login(loginDTO);
        LoginUtils.login(loginVO);
        return Result.success(loginVO);
    }

    /**
     * 修改密码
     *
     * @param passwordDTO 修改密码信息
     * @return 状态码200 “操作成功”
     */
    @PutMapping("/updatePassword")
    public Result<Void> updatePassword(@Validated @RequestBody PasswordDTO passwordDTO) {
        tokenService.updatePassword(passwordDTO);
        return Result.success();
    }

    /**
     * 退出登录
     *
     * @return 状态码200 “操作成功”
     */
    @PostMapping("/logout")
    public Result<Void> logout() {
        LoginUtils.logout();
        return Result.success();
    }

    /**
     * 验证码校验
     *
     * @param code 用户输入的验证码
     * @param uuid 验证码uuid
     */
    private void verifyCaptcha(String code, String uuid) {
        String verifyKey = CacheConstant.CAPTCHA_KEY_NAME + uuid;
        String captcha = RedisUtils.getCacheObject(verifyKey);
        RedisUtils.deleteObject(verifyKey);

        // 验证码过期为空抛异常
        if (captcha == null) {
            throw new CaptchaException("验证码已过期");
        }

        // 验证码错误抛异常
        if (!code.equalsIgnoreCase(captcha)) {
            throw new CaptchaException("验证码错误");
        }
    }
}
